
#include "function.h"
#include "data.h"
#include "math.h"
#include "mseq.h"
//#include "sha1.h"
#include <string>
#include <stdlib.h>


//LPCTSTR GetAppPath()
//{
//	static char	szPath[MAX_PATH];
//	::GetModuleFileName(AfxGetInstanceHandle(), szPath, sizeof(szPath)-1);
//	LPSTR	lp = strrchr(szPath, '\\');
//	if (lp) *lp = 0;
//	return szPath;
//}
//
//void ShowText(CString strText)
//{
//	m_strWindowText += strText;
//
//	/*
//	CFrameWnd *frame = (CFrameWnd *)AfxGetMainWnd();
//	if(frame == NULL) return;
//	CView *view = frame->GetActiveView();
//	if(view == NULL) return;
//
//	m_strWindowText = strText;
//	view->PostMessage(WM_SHOWINFO);
//	*/
//	
//	//CString strWindowText;
//	//view->GetWindowText(strWindowText);
//	//strWindowText += strText;
//	//view->SetWindowText(strWindowText);
//}
//
//void ReadSysParams()
//{
//	CString strFileName = GetAppPath();
//	strFileName += _T("\\dvwatermark.ini");
//
//	m_dvwmSysParam.nWmInfo = GetPrivateProfileInt("SYSTEM", "WMINFO", 888, strFileName);
//	m_dvwmSysParam.nWmKey = GetPrivateProfileInt("SYSTEM", "WMKEY", 14641, strFileName);
//	m_dvwmSysParam.nGeometric = GetPrivateProfileInt("SYSTEM", "GEOMETRIC", 1, strFileName);
//	m_dvwmSysParam.nFrameSync = GetPrivateProfileInt("SYSTEM", "FRAMESYNC", 1, strFileName);
//	m_dvwmSysParam.nGWmStrengthIndex = GetPrivateProfileInt("SYSTEM", "GSTRENGTHINDEX", 0, strFileName);
//	m_dvwmSysParam.nFWmStrengthIndex = GetPrivateProfileInt("SYSTEM", "FSTRENGTHINDEX", 0, strFileName);
//
//	m_dvwmVideoFrame.nFormatIndex = GetPrivateProfileInt("VIDEO", "FORMATINDEX", 0, strFileName);
//	m_dvwmVideoFrame.nWidth = GetPrivateProfileInt("VIDEO", "WIDTH", 352, strFileName);
//	m_dvwmVideoFrame.nHeight = GetPrivateProfileInt("VIDEO", "HEIGHT", 288, strFileName);
//}
//
//void SaveSysParams()
//{
//	CString strFileName = GetAppPath();
//	strFileName += _T("\\dvwatermark.ini");
//
//	char szText[64];
//	sprintf(szText, "%d", m_dvwmSysParam.nWmInfo);
//	WritePrivateProfileString("SYSTEM", "WMINFO", szText, strFileName);
//
//	sprintf(szText, "%d", m_dvwmSysParam.nWmKey);
//	WritePrivateProfileString("SYSTEM", "WMKEY", szText, strFileName);
//
//	sprintf(szText, "%d", m_dvwmSysParam.nGWmStrengthIndex);
//	WritePrivateProfileString("SYSTEM", "GSTRENGTHINDEX", szText, strFileName);
//
//	sprintf(szText, "%d", m_dvwmSysParam.nFWmStrengthIndex);
//	WritePrivateProfileString("SYSTEM", "FSTRENGTHINDEX", szText, strFileName);
//
//	sprintf(szText, "%d", m_dvwmSysParam.nGeometric);
//	WritePrivateProfileString("SYSTEM", "GEOMETRIC", szText, strFileName);
//
//	sprintf(szText, "%d", m_dvwmSysParam.nFrameSync);
//	WritePrivateProfileString("SYSTEM", "FRAMESYNC", szText, strFileName);
//
//	sprintf(szText, "%d", m_dvwmVideoFrame.nFormatIndex);
//	WritePrivateProfileString("VIDEO", "FORMATINDEX", szText, strFileName);
//
//	sprintf(szText, "%d", m_dvwmVideoFrame.nWidth);
//	WritePrivateProfileString("VIDEO", "WIDTH", szText, strFileName);
//
//	sprintf(szText, "%d", m_dvwmVideoFrame.nHeight);
//	WritePrivateProfileString("VIDEO", "HEIGHT", szText, strFileName);
//}


void BlockDCT(short block[][8], double *coeff)
{
    int   j1, i, j;
    double b[8];
    double b1[8];
    double d[8][8];
    double f0=0.7071068,f1=0.4903926,f2=0.4619398,f3=0.4157348,f4=0.3535534;
    double f5=0.2777851,f6=0.1913417,f7=0.0975452;

    for (i = 0; i < 8; i++)
    {
		for (j = 0; j < 8; j++)
		{
			b[j] = block[i][j];
		}
    
		/* Horizontal transform */
		for (j = 0; j < 4; j++)
		{
			j1 = 7 - j;
			b1[j] = b[j] + b[j1];
			b1[j1] = b[j] - b[j1];
		}
    
		b[0] = b1[0] + b1[3];
		b[1] = b1[1] + b1[2];
		b[2] = b1[1] - b1[2];
		b[3] = b1[0] - b1[3];
		b[4] = b1[4];
		b[5] = (b1[6] - b1[5]) * f0;
		b[6] = (b1[6] + b1[5]) * f0;
		b[7] = b1[7];
		d[i][0] = (b[0] + b[1]) * f4;
		d[i][4] = (b[0] - b[1]) * f4;
		d[i][2] = b[2] * f6 + b[3] * f2;
		d[i][6] = b[3] * f6 - b[2] * f2;
		b1[4] = b[4] + b[5];
		b1[7] = b[7] + b[6];
		b1[5] = b[4] - b[5];
		b1[6] = b[7] - b[6];
		d[i][1] = b1[4] * f7 + b1[7] * f1;
		d[i][5] = b1[5] * f3 + b1[6] * f5;
		d[i][7] = b1[7] * f7 - b1[4] * f1;
		d[i][3] = b1[6] * f3 - b1[5] * f5;
    }
  
    /* Vertical transform */

    for (i = 0; i < 8; i++)
    {
		for (j = 0; j < 4; j++)
		{
			j1 = 7 - j;
			b1[j] = d[j][i] + d[j1][i];
			b1[j1] = d[j][i] - d[j1][i];
		}
    
		b[0] = b1[0] + b1[3];
		b[1] = b1[1] + b1[2];
		b[2] = b1[1] - b1[2];
		b[3] = b1[0] - b1[3];
		b[4] = b1[4];
		b[5] = (b1[6] - b1[5]) * f0;
		b[6] = (b1[6] + b1[5]) * f0;
		b[7] = b1[7];
		d[0][i] = (b[0] + b[1]) * f4;
		d[4][i] = (b[0] - b[1]) * f4;
		d[2][i] = b[2] * f6 + b[3] * f2;
		d[6][i] = b[3] * f6 - b[2] * f2;
		b1[4] = b[4] + b[5];
		b1[7] = b[7] + b[6];
		b1[5] = b[4] - b[5];
		b1[6] = b[7] - b[6];
		d[1][i] = b1[4] * f7 + b1[7] * f1;
		d[5][i] = b1[5] * f3 + b1[6] * f5;
		d[7][i] = b1[7] * f7 - b1[4] * f1;
		d[3][i] = b1[6] * f3 - b1[5] * f5;
    }
  
    for (i = 0; i < 8; i++)
		for (j = 0; j < 8; j++)
			coeff[i*8+j] = d[i][j];
			//coeff[i*8+j] = (short)(floor((d[i][j]) + 0.499999));
}

void BlockIDCT(double *coeff_in, short block_out[][8], short maxval)
{
	int    j1, i, j;
	double tmp[8], tmp1[8];
	double e, f, g, h,coeff[8][8],block[8][8];
	static double c0,c1,c2,c3,c4,c5,c6,c7;
	int v;

	for (i=0;i<8;i++)
	for (j=0;j<8;j++)
	  coeff[i][j] = (double)coeff_in[i*8+j];   

	c0=0.7071068;c1=0.4903926;c2=0.4619398;c3=0.4157348;c4=0.3535534;
	c5=0.2777851;c6=0.1913417;c7=0.0975452; 

	/* Horizontal */

	/* Descan coefficients first */

	for (i = 0; i < 8; i++) {
	for (j = 0; j < 8; j++) {
	  tmp[j] =coeff[i][j]; 
	}
	e = tmp[1] * c7 - tmp[7] * c1;
	h = tmp[7] * c7 + tmp[1] * c1;
	f = tmp[5] * c3 - tmp[3] * c5;
	g = tmp[3] * c3 + tmp[5] * c5;

	tmp1[0] = (tmp[0] + tmp[4]) * c4;
	tmp1[1] = (tmp[0] - tmp[4]) * c4;
	tmp1[2] = tmp[2] * c6 - tmp[6] * c2;
	tmp1[3] = tmp[6] * c6 + tmp[2] * c2;
	tmp[4] = e + f;
	tmp1[5] = e - f;
	tmp1[6] = h - g;
	tmp[7] = h + g;

	tmp[5] = (tmp1[6] - tmp1[5]) * c0;
	tmp[6] = (tmp1[6] + tmp1[5]) * c0;
	tmp[0] = tmp1[0] + tmp1[3];
	tmp[1] = tmp1[1] + tmp1[2];
	tmp[2] = tmp1[1] - tmp1[2];
	tmp[3] = tmp1[0] - tmp1[3];

	for (j = 0; j < 4; j++) {
	  j1 = 7 - j;
	  block[i][j] = tmp[j] + tmp[j1];
	  block[i][j1] = tmp[j] - tmp[j1];
	}
	}

	/* Vertical */

	for (i = 0; i < 8; i++) {
	for (j = 0; j < 8; j++) {
	  tmp[j] = block[j][i];
	}
	e = tmp[1] * c7 - tmp[7] * c1;
	h = tmp[7] * c7 + tmp[1] * c1;
	f = tmp[5] * c3 - tmp[3] * c5;
	g = tmp[3] * c3 + tmp[5] * c5;

	tmp1[0] = (tmp[0] + tmp[4]) * c4;
	tmp1[1] = (tmp[0] - tmp[4]) * c4;
	tmp1[2] = tmp[2] * c6 - tmp[6] * c2;
	tmp1[3] = tmp[6] * c6 + tmp[2] * c2;
	tmp[4] = e + f;
	tmp1[5] = e - f;
	tmp1[6] = h - g;
	tmp[7] = h + g;

	tmp[5] = (tmp1[6] - tmp1[5]) * c0;
	tmp[6] = (tmp1[6] + tmp1[5]) * c0;
	tmp[0] = tmp1[0] + tmp1[3];
	tmp[1] = tmp1[1] + tmp1[2];
	tmp[2] = tmp1[1] - tmp1[2];
	tmp[3] = tmp1[0] - tmp1[3];

	for (j = 0; j < 4; j++) {
	  j1 = 7 - j;
	  block[j][i] = tmp[j] + tmp[j1];
	  block[j1][i] = tmp[j] - tmp[j1];
	}
	}    
	for (i=0;i<8;i++)
	  for(j=0;j<8;j++) {
		v = (int) floor (block[i][j] + 0.5);
		block_out[i][j] = (v<0) ? 0 : ((v>maxval) ? maxval : v);
		//block_out[i][j] = (v<-maxval-1) ? -maxval-1 : ((v>maxval) ? maxval : v);
	  }
}

void GetBlock(int width, int height, int horz, int vert, short block[][8], unsigned char *data)
{
	for(int i=0; i<8; i++)
		for(int j=0; j<8; j++)
			block[i][j] = data[(vert*8+i)*width+horz*8+j];
}

void SetBlock(int width, int height, int horz, int vert, short block[][8], unsigned char *data)
{
	for(int i=0; i<8; i++)
		for(int j=0; j<8; j++)
			data[(vert*8+i)*width+horz*8+j] = (unsigned char)block[i][j];
}

void gold6(short d[][63])
{
	Mseq *pn = mseq_create(6, 103, 1);

	for(int i=0; i<63; i++)
	{
		d[0][i] = mseq(pn);
		d[1][i] = ~d[0][i];
		d[1][i] &= 0x01;
	}

	char d1[63];
	for(int i=1; i<63; i++)
	{
		memcpy(d1, &d[0][i], 63-i);
		memcpy(&d1[63-i], &d[0][0], i);
		for(int j=0; j<63; j++)
			d[i+1][j] = d[1][j] ^ d1[j];
	}

	for(int i=0; i<64; i++)
	{
		for(int j=0; j<63; j++)
			if(d[i][j] == 0) d[i][j] = -1;
	}

	mseq_free(pn);
}

void kt(unsigned char s[20], unsigned int k1, unsigned int& key)
{
	int k2;
	
	key = k1;
	k2 = (int)s[0];
	k2 += ((int)s[1]) << 8;
	k2 += ((int)s[2]) << 16;
	k2 += ((int)s[3]) << 24;
	key ^= k2;
	k2 = (int)s[4];
	k2 += ((int)s[4+1]) << 8;
	k2 += ((int)s[4+2]) << 16;
	k2 += ((int)s[4+3]) << 24;
	key ^= k2;
	k2 = (int)s[8];
	k2 += ((int)s[8+1]) << 8;
	k2 += ((int)s[8+2]) << 16;
	k2 += ((int)s[8+3]) << 24;
	key ^= k2;
	k2 = (int)s[12];
	k2 += ((int)s[12+1]) << 8;
	k2 += ((int)s[12+2]) << 16;
	k2 += ((int)s[12+3]) << 24;
	key ^= k2;
	k2 = (int)s[16];
	k2 += ((int)s[16+1]) << 8;
	k2 += ((int)s[16+2]) << 16;
	k2 += ((int)s[16+3]) << 24;
	key ^= k2;
}

void initstatus(unsigned char s[][20], int len, unsigned int key)
{
	srand(key);

	for(int i=0; i<len; i++)
	{
		for(int j=0; j<20; j++)
			s[i][j] = (unsigned char)(255 * rand()/RAND_MAX);
	}
}

void nextstatus(unsigned char s[], unsigned char s1[], unsigned int key, unsigned char rn)
{
	unsigned char s2[25];

	memcpy(s2, s, 20);
	s2[20] = (unsigned char)(key & 0xff);
	s2[21] = (unsigned char)((key>>8) & 0xff);
	s2[22] = (unsigned char)((key>>16) & 0xff);
	s2[23] = (unsigned char)((key>>24) & 0xff);
	s2[24] = rn;
//	sha1(s1, s2, 25);
}

void addqueue(unsigned char sq[][20], unsigned int kq[], int& n_k, unsigned char s[], unsigned int k)
{
	unsigned int key[16];
	unsigned char st[16][20];

	for(int i=0; i<n_k; i++)
	{
		if(kq[i] == k)
		{
			for(int j=0; j<20; j++)
			{
				if(sq[i][j] != s[j])
					break;
			}

			if(i == 20)
			{
				if(i)
				{
					memcpy(st, sq, i*20);
					memcpy(sq[1], st, i*20);
					memcpy(sq, s, 20);

					memcpy(key, kq, i*sizeof(int));
					memcpy(&kq[1], key, i*sizeof(int));
					kq[0] = k;
				}

				return;
			}
		}
	}

	if(n_k < 16)
	{
		if(n_k > 0)
		{
			memcpy(st, sq, n_k*20);
			memcpy(sq[1], st, n_k*20);

			memcpy(key, kq, n_k*sizeof(int));
			memcpy(&kq[1], key, n_k*sizeof(int));
		}

		memcpy(sq, s, 20);
		kq[0] = k;

		n_k ++;
	}
	else
	{
		memcpy(st, sq, 15*20);
		memcpy(sq[1], st, 15*20);
		memcpy(sq, s, 20);

		memcpy(key, kq, 15*sizeof(int));
		memcpy(&kq[1], key, 15*sizeof(int));
		kq[0] = k;
	}
}

bool IsHas(int data[], int len, int d1)
{
	for(int i=0; i<len; i++)
	{
		if(data[i] == d1)
			return true;
	}

	return false;
}
